/**********************************************************************************
**
** Copyright (C) 2009 Jostein Bratlie
** Contact: jostein.bratlie@gmail.com | http://bratlie.info | http://episteme.hin.no
**
** This file is part of GMQtExt, a GMlib and Qt extension library
**
** GMQtExt is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** GMQtExt is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with GMQtExt.  If not, see <http://www.gnu.org/licenses/>.
**
**********************************************************************************/


// local
#include "sceneitem.h"

// header
#include "scenemodel.h"

// GMlib
#include <gmLight>
#include <gmCamera>
#include <gmSceneObject>

namespace GMQtExt {


  SceneModel::SceneModel( const QString& name ) {

    _no_objects = 0;
    _no_lights = 0;
    _no_cameras = 0;

    _root = new SceneItem( name );
    _root->setName( 0 );
    appendRow( _root );
  }

  int SceneModel::getNoCameras() {

    return _no_cameras;
  }

  int SceneModel::getNoLights() {

    return _no_lights;
  }

  int SceneModel::getNoObjects() {

    return _no_objects;
  }

  void SceneModel::populate( GMlib::Scene* scene ) {

    _no_objects = 0;
    _no_lights = 0;
    _no_cameras = 0;

    QList<unsigned int> items;
    QMap<unsigned int, int> items_map;
    for( int i = 0; i < _root->rowCount(); i++ ) {

      items << ((SceneItem*)_root->child(i))->getName();
      items_map[((SceneItem*)_root->child(i))->getName()] = i;
    }

    for( int i = 0; i < scene->getSize(); i++ ) {

      GMlib::SceneObject *obj = (*(scene))[i];
      if( items.contains( obj->getName() ) ) {

        SceneItem *item = (SceneItem*)_root->child(items_map[obj->getName()]);
        populate( obj, item );

        items.removeOne( obj->getName() );
      }
      else {

        // The item
        SceneItem *item;
        item = new SceneItem(
            QString( "%1 [%2]").arg( obj->getIdentity().c_str() ).arg( obj->getName() ) );

        if( !obj->isVisible() )
          item->setBackground( QBrush( QColor("LightGray") ) );

        // Item Properties
        item->setName( obj->getName() );

        _root->appendRow( item );

        populate( obj, item );
      }


      // Count Object(s)
      GMlib::Light *light = dynamic_cast<GMlib::Light*>( obj );
      if( light )
        _no_lights++;

      GMlib::Camera *cam = dynamic_cast<GMlib::Camera*>( obj );
      if ( cam )
        _no_cameras++;

      _no_objects++;
    }

    // Remove the items that is no longer there
    for( int i = 0; i < items.size(); i++ )
      _root->removeRow( items_map[items[i]] );
  }

  void SceneModel::populate( GMlib::SceneObject *parent_obj, SceneItem* parent_item ) {

    QList<unsigned int> items;
    QMap<unsigned int, int> items_map;
    for( int i = 0; i < parent_item->rowCount(); i++ ) {

      items << ((SceneItem*)parent_item->child(i))->getName();
      items_map[((SceneItem*)parent_item->child(i))->getName()] = i;
    }

    for( int i = 0; i < parent_obj->getChildren().getSize(); i++ ) {

      GMlib::SceneObject *obj = parent_obj->getChildren()[i];
      if( items.contains( obj->getName() ) ) {

        SceneItem *item = (SceneItem*)parent_item->child(items_map[obj->getName()]);
        populate( obj, item );

        items.removeOne( obj->getName() );
      }
      else {

        // The item
        SceneItem *item;
        item = new SceneItem(
            QString( "%1 [%2]").arg( obj->getIdentity().c_str() ).arg( obj->getName() ) );

        if( !obj->isVisible() )
          item->setBackground( QBrush( QColor("LightGray") ) );

        // Item Properties
        item->setName( obj->getName() );

        parent_item->appendRow( item );

        populate( obj, item );
      }


      // Count Object(s)
      GMlib::Light *light = dynamic_cast<GMlib::Light*>( obj );
      if( light )
        _no_lights++;

      GMlib::Camera *cam = dynamic_cast<GMlib::Camera*>( obj );
      if ( cam )
        _no_cameras++;

      _no_objects++;

    }

    // Remove the items that is no longer there
    for( int i = 0; i < items.size(); i++ )
      parent_item->removeRow( items_map[items[i]] );
  }

  void SceneModel::set( GMlib::Scene* scene ) {

    if( !scene )
      return;

    populate( scene );
  }




} // END namespace GMQtExt
